﻿using Sinacor.Infra.Common.Exceptions;
using System;
using Sinacor.Infra.UI.Common;
using System.Collections.ObjectModel;
using System.Linq;

namespace Sinacor.UI.Bovespa.Contabil.Presenter
{
    public class CadastroDespesaNota : BasePresenter<ICadastroDespesaNota>
    {
        private Communication.DespesaNota _communicationDespesaNota;
        private Communication.TipoDespesa _communicationTipoDespesa;
        private Communication.EventoContabil _communicationEventoContabil;

        private Model.Parameter.FiltroTipoDespesaPeriodo _filtroTipoDespesaPeriodo; 
        
        private ModelCollection<Model.DespesaNota> _listaDespesaNota;
        private ModelCollection<Model.TipoDespesa> _listaTipoDespesa;
        
        private Model.DespesaNota _despesaNota;
        private Model.TipoDespesa _tipoDespesa;
        
        public ObservableCollection<EnumWrapper<Model.Enum.TipoBaseDespesa>> ListaTipoBaseDespesa { get; set; }

        public ModelCollection<Model.EventoContabil> ListaEventosContabeis { get; set; }

        public CadastroDespesaNota(ICadastroDespesaNota view)
            : base(view)
        {
            
            _communicationDespesaNota = new Sinacor.UI.Bovespa.Contabil.Communication.DespesaNota(this.Session);
            _communicationTipoDespesa = new Sinacor.UI.Bovespa.Contabil.Communication.TipoDespesa(this.Session);
            _communicationEventoContabil = new Sinacor.UI.Bovespa.Contabil.Communication.EventoContabil(this.Session);

            _filtroTipoDespesaPeriodo = new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroTipoDespesaPeriodo();    
            _listaDespesaNota = new ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.DespesaNota>();
            _listaTipoDespesa = new ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.TipoDespesa>();
            _despesaNota = new Sinacor.UI.Bovespa.Contabil.Model.DespesaNota();
            _despesaNota.EventoContabil = new Sinacor.UI.Bovespa.Contabil.Model.EventoContabil ();

            _tipoDespesa = new Sinacor.UI.Bovespa.Contabil.Model.TipoDespesa();

            this.ListaTipoBaseDespesa = new ObservableCollection<EnumWrapper<Sinacor.UI.Bovespa.Contabil.Model.Enum.TipoBaseDespesa>>();

            this.ListaTipoBaseDespesa = EnumWrapper<Model.Enum.TipoBaseDespesa>.GetEnums(
                Model.Enum.TipoBaseDespesa.SobreCorretagem, Model.Enum.TipoBaseDespesa.SobreDesconto, Model.Enum.TipoBaseDespesa.SobreVolume);

            this.View.AtualizarListaBaseDespesa();
        }

        public ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.TipoDespesa> ListaTipoDespesa
        { get { return _listaTipoDespesa; } set { _listaTipoDespesa = value; } }

        public ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.DespesaNota> ListaDespesaNota
        { get { return _listaDespesaNota; } set { _listaDespesaNota = value; } }

        public Model.Parameter.FiltroTipoDespesaPeriodo FiltroTipoDespesaPeriodo
        {
            get { return _filtroTipoDespesaPeriodo; }
            set { _filtroTipoDespesaPeriodo = value; }
        }

        public bool AlterarDespesaNota(Model.DespesaNota model)
        {
            if (this.ValidarDespesaNota(model))
            {
                Model.Conflito _conflito = new Sinacor.UI.Bovespa.Contabil.Model.Conflito();
                _conflito = _communicationDespesaNota.VerificarConflitoPeriodo(model);

                if (_conflito.ExisteConflito)
                {
                    if (_conflito.PermiteAjuste)
                    {
                        if (this.View.ConfirmarPermiteAjuste())
                        {
                            _communicationDespesaNota.AlterarDespesaNota(model);
                            this.View.InformarDespesaAlteradaSucesso();
                            return true;
                        }
                    }
                    else
                    {
                        this.View.InformarConflitoSemAjuste();
                        return false;
                    }
                }
                else
                {
                    try
                    {
                        _communicationDespesaNota.AlterarDespesaNota(model);
                        
                        this.View.InformarDespesaAlteradaSucesso();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        HandleException(ex);
                        return false;
                    }
                }
            }
            else
            {
                return false;
            }
            return false;
        }

        public bool AlterarTipoDespesa(Model.TipoDespesa model)
        {
            if (this.ValidarTipoDespesa(model))
            {
                try
                {
                    _communicationTipoDespesa.AlterarTipoDespesa(model);
                    this.View.InformarTipoDespesaAlteradoSucesso();
                    return true;
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                    this.AtribuirFoco(((BusinessException)(ex)).ErrorNumber);
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        public void ConsultarTiposDespesasPeriodo()
        {
            _listaTipoDespesa = _communicationTipoDespesa.ConsultarTiposDespesasPeriodo(_filtroTipoDespesaPeriodo);
            if (_listaTipoDespesa == null || _listaTipoDespesa.Count == 0) 
            {
                this.View.InformarNenhumRegistroEncontrado();
            } 
            
            this.View.AtualizarTipoDespesa();
        }

        public bool ExcluirDespesaNota(Model.DespesaNota model)
        {
            try
            {
                Model.Parameter.FiltroDespesaNotaChave _filtroExclusao = new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroDespesaNotaChave();
                _filtroExclusao.Codigo = model.Codigo;
                _filtroExclusao.PregaoInicial = (DateTime)model.PregaoInicial;

                if (this.View.ConfirmarExclusaoDespesa())
                {
                    _communicationDespesaNota.ExcluirDespesaNota(_filtroExclusao);
                    this.View.InformarExclusaoDespesaSucesso();
                    return true;
                }
            }
            catch (Exception e)
            {
                HandleException(e);
            }

            return false;
        }

        public bool ExcluirTipoDespesa(Model.TipoDespesa model)
        {
            if (model == null)
            {
                this.View.InformarSelecioneTipoDespesa();
                return false;
            }
            else
            {
                try
                {
                    Model.Parameter.FiltroTipoDespesaChave _filtroExclusao = new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroTipoDespesaChave();
                    _filtroExclusao.Codigo = model.Codigo;

                    if (this.View.ConfirmarExclusaoTipoDespesa())
                    {
                        _communicationTipoDespesa.ExcluirTipoDespesa(_filtroExclusao);
                        this.View.InformarExclusaoTipoDespesaSucesso();
                        return true;
                    }
                }
                catch (Exception e)
                {
                    HandleException(e);
                }
                return false;
            }
        }

        public bool IncluirDespesaNota(Model.DespesaNota model)
        {
                if (this.ValidarDespesaNota(model))
                { 
                    Model.Conflito _conflito = new Sinacor.UI.Bovespa.Contabil.Model.Conflito();
                    _conflito = _communicationDespesaNota.VerificarConflitoPeriodo(model);

                    if (_conflito.ExisteConflito)
                    {
                        if (_conflito.PermiteAjuste)
                        {
                            if (this.View.ConfirmarPermiteAjuste())
                            {
                                try
                                {
                                    _communicationDespesaNota.IncluirAjustarDespesaNota(model);
                                    this.View.InformarDespesaIncluidaSucesso();
                                    return true;
                                }
                                catch (Exception e)
                                {
                                    HandleException(e);
                                    this.AtribuirFoco(((BusinessException)(e)).ErrorNumber);
                                    return false;
                                }
                            }
                        }
                        else
                        {
                            this.View.InformarConflitoSemAjuste();
                            return false;
                        }
                    }
                    else
                    {
                        try
                        {
                            _communicationDespesaNota.IncluirDespesaNota(model);
                            this.View.InformarDespesaIncluidaSucesso();
                            return true;
                        }
                        catch (Exception e)
                        {
                            HandleException(e);
                            return false;
                        }
                    }
                }
                else
                {
                    return false;
                }
                return false;
        }

        public bool IncluirTipoDespesa(Model.TipoDespesa model)
        {
            if ((model.Codigo != null) && (model.Codigo != string.Empty))
            {
                if (this.ValidarTipoDespesa(model))
                {
                    try
                    {
                        _communicationTipoDespesa.IncluirTipoDespesa(model);
                        this.View.InformarTipoDespesaIncluidoSucesso();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        HandleException(ex);
                        this.AtribuirFoco(((BusinessException)(ex)).ErrorNumber);
                        return false;
                    }
                 }
                else
                {
                    return false;
                }
            }
            else
            {
                this.View.InformarCodigoTipoDespesaObrigatorio();
                this.View.AtribuirFocoCodigoTipoDespesa();
                return false;
            }
        }

        private void AtribuirFoco(int ErroNumber)
        {
            if (ErroNumber == 109220)
                this.View.AtribuirFocoCodigoTipoDespesa();

            if (ErroNumber == 109218)
                this.View.AtribuirFocoDescricaoTipoDespesa();

            if (ErroNumber == 109234)
                this.View.AtribuirFocoPregaoInicialDespesa();

        }

        public void Inicializar()
        {
            this.ConsultarTiposDespesasPeriodo();
        }

        public void ConsultarDespesasNota(Model.Parameter.FiltroDespesaNota parameter)
        {
            ConsultarEventosContabeis();

            _listaDespesaNota = new ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.DespesaNota>();
            Model.Parameter.FiltroDespesaNota _filtroDespesaNota  = new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroDespesaNota();
            _filtroDespesaNota.Codigo = parameter.Codigo; 
            _listaDespesaNota = _communicationDespesaNota.ConsultarDespesasNota(_filtroDespesaNota);
            this.View.AtualizarDespesaNota();
        }
            
        private bool ValidarDespesaNota(Model.DespesaNota request)
        {
            if (this.ValidarDespesaNotaObrigatoriedade(request))
            {
                if (this.ValidarDespesaNotaNegocio(request))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        private bool ValidarDespesaNotaNegocio(Model.DespesaNota request)
        {
            if (!((request.EventoContabil.Codigo == 57) || (request.EventoContabil.Codigo > 200)))
            {
                this.View.InformarEventoNaoPermitido();
                return false;
            }

            if (!(request.ValorMinimo < Convert.ToDecimal(9999999.99)))
            {
                this.View.InformarValorMinimoNaoPermitido();
                return false;
            }

            if (!(request.ValorMinimo <= request.ValorMaximo))
            {
                this.View.InformarValorMinimoInvalido();
                return false;
            }

            if (!(request.ValorMaximo < Convert.ToDecimal(9999999.99)))
            {
                this.View.InformarValorMaximoNaoPermitido();
                return false;
            }

            if (!(request.PregaoInicial <= request.PregaoFinal))
            {
                this.View.InformarPregaoInicialInvalido();
                return false;
            }                

            return true;
        }

        private bool ValidarDespesaNotaObrigatoriedade(Model.DespesaNota request)
        {
            if (request.Codigo == null)
            {
                this.View.InformarDespesaObrigatorio();
                return false;            
            }

            if (request.PregaoInicial == null)
            {
                this.View.InformarPregaoInicialObrigatorio();
                return false;
            }

            if (request.PregaoFinal == null)
            {
                this.View.InformarPregaoFinalObrigatorio();
                return false;
            }

            if (request.PercentualDespesa == null)
            {
                this.View.InformarPercentualObrigatorio();
                return false;
            }

            if (request.ValorMinimo == null)
            {
                this.View.InformarValorMinimoObrigatorio();
                return false;
            }

            if (request.ValorMaximo == null)
            {
                this.View.InformarValorMaximoObrigatorio();
                return false;
            }

            if (request.BaseDespesa == null)
            {
                this.View.InformarBaseDespesaObrigatorio();
                return false;
            }

            if (request.EventoContabil == null || request.EventoContabil.Codigo == 0)
            {
                this.View.InformarEventoContabilObrigatorio();
                return false;
            }

            return true;
        }

        public bool ValidarTipoDespesa(Model.TipoDespesa request)
        {
            if ((request.Descricao == null) || (request.Descricao == string.Empty))
            {
                this.View.InformarDescricaoTipoDespesaObrigatorio();
                this.View.AtribuirFocoDescricaoTipoDespesa();
                return false;
            }
            else
            {
                return true;
            }
        }

        public void VerificarExistemOperacoesNaoSalvas()
        {

        }

        public void ConsultarEventosContabeis()
        {
            Model.Parameter.FiltroEventoContabil _filtro = new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroEventoContabil();

            ModelCollection<Model.EventoContabil> _listaTodosEventosContabeis = new ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.EventoContabil>();

            _listaTodosEventosContabeis = _communicationEventoContabil.ConsultarEventosContabeis(_filtro);

            this.ListaEventosContabeis = new ModelCollection<Sinacor.UI.Bovespa.Contabil.Model.EventoContabil>();

            IQueryable Retorno;

            IQueryable<Model.EventoContabil> _eventosFiltrados = _listaTodosEventosContabeis.AsQueryable();

            Retorno = from prop in _eventosFiltrados where prop.Codigo == 57 || prop.Codigo > 200 select prop;

            foreach (Model.EventoContabil item in Retorno)
            {
                this.ListaEventosContabeis.Add(item);
            }

            //Retorno = from prop in _eventosFiltrados where prop.Codigo > 200 select prop;

            //foreach (Model.EventoContabil item in Retorno)
            //{
            //    this.ListaEventosContabeis.Add(item);
            //}

            this.View.AtualizarListaEventoContabil();
        }

    }
}